<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //1 var let cont 

        // var 既能局部，又能全局
        var a = 20
        var a = 30
        console.log(a);

        // 在函数中使⽤使⽤ var 声明变量时候，该变量是局部的
        var a1 = 20
        function change(){
            var a1 = 30
        }
        change()
        console.log(a1); // 20

        // ⽽如果在函数内不使⽤ var ，该变量是全局的
        var a2 = 20
        function change2(){
            a2 = 30
        }
        change2()
        console.log(a2) // 30

        // 区别1 变量提升
        console.log(a3) // undefined
        var a3 = 10
        // let
        // console.log(b) // Cannot access 'b' before initialization
        // let b = 10
        // const
        // console.log(c) // Cannot access 'c' before initialization
        // const c = 10

        // 区别2. 暂时性死区---可以把暂时性死区 理解为没有提前声明就调用导致的把报错
        // var 不存在暂时性死区 let 和 const 存在暂时性死区，只有等到声明变量的那⼀⾏代码出现，才可以获取和使⽤该变量

        // 区别3.块级作用域
        // let const 有  var 没有

        // 区别4.可以重复声明 var 可以, let const 不行
        // 可以用const 申明一个 computed的函数，因为const 保证的是变量标识符的绑定不可变（即变量名指向的内存地址不变），而不是该地址存储的内容不可变。
        // computed() 返回的响应式引用对象上（内存地址不变）

        // 2 扩展运算符...
        // 《1》
        console.log(...[1,2,3]);
        const number = [4,38]
        const add = (x,y)=>{
            console.log('求和',x+y);
            return x + y
        }
        add(...number)

        // 《2》 数组合并
        const arr1 = ['a', 'b'];
        const arr2 = ['c'];
        const arr3 = ['d', 'e'];
        console.log([...arr1, ...arr2, ...arr3])
        // [ 'a', 'b', 'c', 'd', 'e' ]

        // <3> 将字符串转为真正的数组
        console.log([...'hello']);


        // 3  Array.form() 和  Array.of()
        // 将Array.form() 两类对象转为真正的数组
        let arrayLike = {
            '0': 'a',
            '1': 'b',
            '2': 'c',
            length: 3
        };
        let arr4 = Array.from(arrayLike); // ['a', 'b', 'c']
        console.log('arr4',arr4);

        // 还可以接受第⼆个参数，⽤来对每个元素进⾏处理，将处理后的值放⼊返回的数组
        let arr5 = Array.from([1, 2, 3], (x) => x * x)
        console.log('arr5',arr5);
        
        // 4 Array.of()⽤于将⼀组值，转换为数组
        console.log(Array.of(3,11,8)); // [3, 11, 8]

        // 5 fill()-- fill(value, start, end) 第一个参数是必须的，第二个和第三个是可选的
        // value：必需。用来填充数组的值。
        // start：可选。开始填充的位置，默认是 0。
        // end：可选。停止填充的位置（不包括该位置），默认是 array.length。

        const arr6 = [1, 2, 3, 4, 5]
        arr6.fill(0,2,4)
        console.log(arr6); //[1, 2, 0, 0, 5]

        // 6 copyWithin(target, start, end)--end不包含这个位置
        // target：必需。开始复制到的位置（索引）。如果为负数，则从末尾开始计算。
        // start：可选。开始复制的位置（索引），默认是 0。如果为负数，则从末尾开始计算。
        // end：可选。停止复制的位置（不包括该位置），默认是 array.length。如果为负数，则从末尾开始计算
        const arr7 = ['a', 'b', 'c', 'd', 'e'];
        arr7.copyWithin(0, 3, 5);
        console.log(arr4); // ['d', 'e', 'c', 'd', 'e']

        // 7 entries()，keys()，values(),.... ， 

        const obj1 = {
            'a': 1,
            'b': 2,
            'c': 3,
            'd': 4,
        }
        // keys() 是对键名的遍历
        console.log('keys',Object.keys(obj1)); //['a','b','c','d']
        // values() 是对键值的遍历
        console.log('values',Object.values(obj1)); // [1,2,3,4]
        // entries() 是对键值对的遍历
        console.log('entries',Object.entries(obj1));// [['a', 1],['b', 2],['c', 3],['d', 4]]

        const c = [['a', 1],['b', 2],['c', 3],['d', 4]]
        console.log('fromEntries',Object.fromEntries(c)) // {a: 1, b: 2, c: 3, d: 4}

        // Object.is() 是 JavaScript 中的一个方法，用于判断两个值是否相同
        console.log(Object.is(0, -0)); // false
        console.log(Object.is(NaN, NaN)); // true
        console.log(Object.is(5, 5)); // true
        console.log(Object.is('abc', 'abc')); // true
        console.log(Object.is({}, {})); // false (

        // 8 数组扁平化 flat()，flatMap() 、尾递归
        // <1> flat() 不传是默认处理2维数组，传2就是默认处理3维数组
        const arr8 = [1,2,3,[4,5,[6,7]]].flat(2)
        const arr9= [1,2,3,[9,6,]].flat()
        console.log('arr8',arr8);
        console.log('arr9',arr9);

        // <2> flatMap() 不改变原数组，返回一个新的数组
        const arr10 = [2,3,4]
        console.log(arr10.flatMap(v=>[v,v*2])); //[2, 4, 3, 6, 4, 8]
        
    </script>
</body>
</html>